<template>
  <div :id="editorId" class="editor" :style="'height:' + height"></div>
</template>

<script lang="ts" setup name="CodeEditor">
import { EditorView, basicSetup } from 'codemirror';
import { EditorState } from '@codemirror/state';
import { autocompletion } from '@codemirror/autocomplete';
import { python } from '@codemirror/lang-python';
const editorView = ref(null);
const code = ref('');
const emit = defineEmits(['update:modelValue']);
const prop = defineProps({
  height: {
    type: String,
    default: '220px'
  },
  readonly: {
    type: Boolean,
    default: false
  },
  editorId: {
    type: String,
    default: 'editor',
    required: true
  },
  modelValue: {
    type: String,
    default: ''
  }
});
const flag = ref(false);
const initData = () => {
  if (!flag.value) {
    const state = EditorState.create({
      doc: code.value,
      extensions: [
        basicSetup,
        python(),
        autocompletion(),
        EditorState.readOnly.of(prop.readonly),
        EditorView.updateListener.of((viewUpdate) => {
          code.value = viewUpdate.state.doc.toString();
          emit('update:modelValue', code.value);
        })
      ]
    });
    editorView.value = new EditorView({
      state,
      parent: document.querySelector('#' + prop.editorId)
    });
    flag.value = true;
  }
};
const setText = (text) => {
  if (editorView.value) {
    editorView.value.dispatch({
      changes: {
        from: 0,
        to: editorView.value.state.doc.length,
        insert: text
      }
    });
  }
};
defineExpose({
  setText
});
watch(
  () => prop.modelValue,
  () => {
    if (prop.modelValue) {
      code.value = prop.modelValue;
      initData();
      //   setText(code.value);
    }
  }
);
onMounted(async () => {
  if (prop.modelValue) {
    code.value = prop.modelValue;
    initData();
  }
});
</script>

<style lang="scss" scoped>
.editor {
  border: 1px solid #ccc;
  margin: 8px;
  overflow-y: auto;
}
</style>
